//
//  DownloadManager.m
//  ImGuider
//
//  Created by llt on 2017/8/4.
//  Copyright © 2017年 AudioCtrip. All rights reserved.
//

#import "DownloadManager.h"
#import "DownloadListDAO.h"
#import "MCDownloader.h"

#import "FileManager.h"
#import <SDWebImagePrefetcher.h>

@interface DownloadManager ()

@property (atomic, strong) NSMutableDictionary *modelDictory;
@property (nonatomic, strong) MCDownloader *downloader;

@property (nonatomic, strong) NSOperationQueue *oprationQueue;

@end

@implementation DownloadManager

+ (instancetype)sharedManager {
    
    static id instance;
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        
        instance = [[self alloc] init];
    });
    
    return instance;
}

- (instancetype)init {
    
    self = [super init];
    if (self) {
        
        _modelDictory = [NSMutableDictionary dictionary];
        _downloader = [MCDownloader sharedDownloader];
        _downloader.maxConcurrentDownloads = 3;
        _oprationQueue = [[NSOperationQueue alloc] init];
        _oprationQueue.maxConcurrentOperationCount = 1;//指定池子的并发数
    }
    return self;
}

/**
 是否下载完成
 
 @param URLString 下载链接
 @return 是否完成
 */
- (BOOL)isDownloadCompletedForURLString:(NSString *)URLString {
    
    MCDownloadReceipt *receipt = [self.downloader downloadReceiptForURLString:URLString];
    
    if (receipt.state == DownloadStateCompleted) {
        
        return YES;
    }
    
    return NO;
}

- (NSString *)localFilePathForURLString:(NSString *)URLString {
    
    MCDownloadReceipt *receipt = [self.downloader downloadReceiptForURLString:URLString];
    if (receipt.state == DownloadStateCompleted) {
        
        return receipt.filePath;
    }
    return nil;
}

- (long long)localFileSizeForURLString:(NSString *)URLString {
    
    MCDownloadReceipt *receipt = [self.downloader downloadReceiptForURLString:URLString];
    
    if (receipt.state == DownloadStateCompleted) {
        
        long long bytes = receipt.totalBytesWritten;
        
        return bytes;
    }
    return 0;
}

- (MCDownloadReceipt *)downloadSateForURLString:(NSString *)URLString {
    
    MCDownloadReceipt *receipt = [self.downloader downloadReceiptForURLString:URLString];
    
    return receipt;
}

- (DownloadState)downloadSateForModel:(LineModel *)model progress:(CGFloat *)progress {
    
    NSInteger downloadCompleteCount = 0;
    NSInteger downloadFailedCount = 0;
    for (ScenicPoint *point in model.records) {
        
        MCDownloadReceipt *receipt = [self.downloader downloadReceiptForURLString:point.playpath];
        
        if (receipt.state == DownloadStateCompleted) {
            downloadCompleteCount ++;
        } else if (receipt.state == DownloadStateFailed) {
            downloadFailedCount ++;
        }
    }
    
    DownloadState state = DownloadStateDownloading;
    
    CGFloat p = (downloadFailedCount + downloadCompleteCount) * 1.0f / model.records.count;
    
    if (p >= 1) {
        p = 1;
        
        if (downloadFailedCount > 0) {
            state = DownloadStateFailed;
        } else {
            state = DownloadStateCompleted;
        }
        
    } else if (p < 0) {
        p = 0;
    }
    
    *progress = p;
    
    return state;
}

/**
 增加下载
 
 @param lineModel lineModel对象
 */


/**
 增加下载
 
 @param lineModel lineModel对象
 
 */
- (void)addDownloadWithLineModel:(LineModel *)lineModel {
    
    if (lineModel.unionid.length == 0) {
        return;
    }
    @weakify(self);
    [self.oprationQueue addOperationWithBlock:^{
        @strongify(self);
        
        IGLog(@"cdsafasfasdfa %@",[NSThread currentThread]);
        [DownloadListDAO insertLineModel:lineModel];
        [self downloadPictures:lineModel];
        [DownloadListDAO changeLineModelState:DownloadStateDownloading unionid:lineModel.unionid];
        
        [[NSNotificationCenter defaultCenter] postNotificationName:kDownloadBeginDownNotif object:@{kDownloadNotifLineID:lineModel.unionid, kDownloadState : @(DownloadStateDownloading)}];
        
        for (ScenicPoint *point in lineModel.records) {
            
            NSString *pathStr = point.playpath;
            if (pathStr.length == 0) {
                continue;
            }
            
            [self.modelDictory setObject:lineModel.unionid forKey:pathStr];
            
            
            [self.downloader downloadDataWithURL:[NSURL URLWithString:pathStr] progress:nil completed:^(MCDownloadReceipt * _Nullable receipt, NSError * _Nullable error, BOOL finished) {
                
                [self notifyDownloadStateWithReceipt:receipt];
            }];
        }
        
    }];
}


- (void)notifyDownloadStateWithReceipt:(MCDownloadReceipt *)receipt {
    
    [self.oprationQueue addOperationWithBlock:^{
        
        NSString *uniond = self.modelDictory[receipt.url];
        
        if (!uniond) {
            return;
        }
        
        NSMutableArray *urlArray = [NSMutableArray array];
        [self.modelDictory enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
            
            if ([obj isEqualToString:uniond]) {
                [urlArray addObject:key];
            }
        }];
        
        NSInteger downloadCompleteCount = 0;
        NSInteger downloadFailedCount = 0;
        for (NSString *dURL in urlArray) {
            
            MCDownloadReceipt *receipt = [self.downloader downloadReceiptForURLString:dURL];
            
            if (receipt.state == DownloadStateCompleted) {
                downloadCompleteCount ++;
            } else if (receipt.state == DownloadStateFailed) {
                downloadFailedCount ++;
            }
        }
        
        DownloadState modelState = 0;
        
        NSInteger completeCount = downloadFailedCount + downloadCompleteCount;
        
        if (completeCount == urlArray.count) {
            
            if (downloadFailedCount > 0) {
                
                modelState = DownloadStateFailed;
            } else {
                
                modelState = DownloadStateCompleted;
            }
            
            [DownloadListDAO changeLineModelState:modelState unionid:uniond];
            [self.modelDictory removeObjectsForKeys:urlArray];
        }
        
        DownloadState state = (receipt.state == DownloadStateCompleted) ? DownloadStateCompleted : DownloadStateFailed;
        
        [[NSNotificationCenter defaultCenter] postNotificationName:kDownloadCompleteDownNotif object:nil userInfo:@{kDownloadNotifLineID : uniond, kDownloadState : @(state)}];
    }];
}

- (void)downloadPictures:(LineModel *)model {
    
    for (ScenicPoint *point in model.records) {
        
        for (NSString *url in point.pictureArray) {
            
            if (!url) {
                continue;
            }
            
            NSURL *imageURL = [NSURL URLWithString:url];
            
            [[SDWebImageDownloader sharedDownloader] downloadImageWithURL:imageURL options:SDWebImageDownloaderContinueInBackground progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished) {
                
                [FileManager saveImage:image InDirectory:kPath_ImageSave url:url];
            }];
        }
    }
    
    for (NSString *mapStr in model.mapPicArray) {
        
        if (!mapStr) {
            continue;
        }
        
        NSURL *imageURL = [NSURL URLWithString:mapStr];
        
        [[SDWebImageDownloader sharedDownloader] downloadImageWithURL:imageURL options:SDWebImageDownloaderContinueInBackground progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished) {
            
            [FileManager saveImage:image InDirectory:kPath_ImageSave url:mapStr];
        }];
    }
    
}


/**
 停止下载，删除对象
 
 @param lineModel lineModel对象
 */
- (void)deleteDownloadWithLineModel:(LineModel *)lineModel {
    
    @weakify(self);
    [self.oprationQueue addOperationWithBlock:^{
        @strongify(self);
        
        for (ScenicPoint *point in lineModel.records) {
            
            MCDownloadReceipt *receipt = [self.downloader downloadReceiptForURLString:point.playpath];
            
            [self.downloader remove:receipt completed:nil];
            
            
            
            for (NSString *url in point.pictureArray) {
                
                if (!url) {
                    continue;
                }
                
                [FileManager deleteImageInDirectory:kPath_ImageSave url:url];
            }
        }

        for (NSString *mapStr in lineModel.mapPicArray) {
            
            if (!mapStr) {
                continue;
            }
            
            [FileManager deleteImageInDirectory:kPath_ImageSave url:mapStr];
        }
     

        [DownloadListDAO deleteLineModel:lineModel];
        
    }];
}

/**
 停止下载，不删除对象
 
 @param lineModel lineModel对象
 */
- (void)pauseWithLineModel:(LineModel *)lineModel {
    
    [self.oprationQueue addOperationWithBlock:^{
        
        for (ScenicPoint *point in lineModel.records) {
             MCDownloadReceipt *receipt = [self.downloader downloadReceiptForURLString:point.playpath];
            
            if (receipt.state != DownloadStateCompleted) {
                
                [self.downloader cancel:receipt completed:nil];
            }
        }
        
        [DownloadListDAO changeLineModelState:DownloadStateSuspened unionid:lineModel.unionid];
        
        [[NSNotificationCenter defaultCenter] postNotificationName:kDownloadBeginDownNotif object:@{kDownloadNotifLineID:lineModel.unionid, kDownloadState : @(DownloadStateSuspened)}];
    }];
}

- (void)deleteAllDownloading {
    
    [self.oprationQueue addOperationWithBlock:^{
        
        __block NSArray *downloadArray = nil;
        
        [DownloadListDAO getLineModelListWithState:DownloadStateDownloading block:^(NSArray<LineModel *> *dataArray) {
            downloadArray = dataArray;
        }];
        
        for (LineModel *model in downloadArray) {
            
            [DownloadListDAO changeLineModelState:DownloadStateSuspened unionid:model.unionid];
            
            for (ScenicPoint *point in model.records) {
                
                MCDownloadReceipt *receipt = [self.downloader downloadReceiptForURLString:point.playpath];
                
                if (receipt.state <= DownloadStateDownloading) {
                    
                    [self.downloader remove:receipt completed:nil];
                }
            }
        }
    }];
}

@end
